package com.cencat.driver.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cencat.common.result.Result;
import com.cencat.driver.entity.DriverMessage;
import com.cencat.driver.service.DriverMessageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 司机消息管理控制器
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/driver-message")
@RequiredArgsConstructor
@Tag(name = "司机消息管理", description = "司机端系统 - 司机消息管理接口")
public class DriverMessageController {

    private final DriverMessageService driverMessageService;

    @GetMapping("/info/{id}")
    @Operation(summary = "获取消息信息", description = "根据消息ID获取消息详细信息")
    public Result<DriverMessage> getMessageInfo(
            @Parameter(description = "消息ID", required = true) @PathVariable Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            DriverMessage message = driverMessageService.getById(id, tenantId);
            if (message == null) {
                return Result.error("消息不存在");
            }
            return Result.success(message, "获取消息信息成功");
        } catch (Exception e) {
            log.error("获取消息信息异常: id={}, tenantId={}", id, tenantId, e);
            return Result.error("获取消息信息失败: " + e.getMessage());
        }
    }

    @GetMapping("/driver/{driverId}")
    @Operation(summary = "获取司机消息列表", description = "根据司机ID获取其消息列表")
    public Result<List<DriverMessage>> getMessagesByDriverId(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "是否已读") @RequestParam(required = false) Boolean isRead,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            List<DriverMessage> messages = driverMessageService.getByDriverId(driverId, messageType, isRead, tenantId);
            return Result.success(messages, "获取司机消息列表成功");
        } catch (Exception e) {
            log.error("获取司机消息列表异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("获取司机消息列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/type/{messageType}")
    @Operation(summary = "根据类型获取消息列表", description = "根据消息类型获取消息列表")
    public Result<List<DriverMessage>> getMessagesByType(
            @Parameter(description = "消息类型", required = true) @PathVariable Integer messageType,
            @Parameter(description = "司机ID") @RequestParam(required = false) Long driverId,
            @Parameter(description = "是否已读") @RequestParam(required = false) Boolean isRead,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            List<DriverMessage> messages = driverMessageService.getByMessageType(messageType, driverId, isRead, tenantId);
            return Result.success(messages, "获取消息列表成功");
        } catch (Exception e) {
            log.error("根据类型获取消息列表异常: messageType={}, tenantId={}", messageType, tenantId, e);
            return Result.error("获取消息列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/list")
    @Operation(summary = "获取消息列表", description = "分页获取消息列表，支持多条件筛选")
    public Result<IPage<DriverMessage>> getMessageList(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Long current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Long size,
            @Parameter(description = "司机ID") @RequestParam(required = false) Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "是否已读") @RequestParam(required = false) Boolean isRead,
            @Parameter(description = "消息标题") @RequestParam(required = false) String title,
            @Parameter(description = "开始时间") @RequestParam(required = false) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) LocalDateTime endTime,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            IPage<DriverMessage> result = driverMessageService.getPageList(current, size, driverId, messageType, isRead, title, startTime, endTime, tenantId);
            return Result.success(result, "获取消息列表成功");
        } catch (Exception e) {
            log.error("获取消息列表异常: tenantId={}", tenantId, e);
            return Result.error("获取消息列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/unread/{driverId}")
    @Operation(summary = "获取未读消息列表", description = "获取指定司机的未读消息列表")
    public Result<List<DriverMessage>> getUnreadMessages(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            List<DriverMessage> result = driverMessageService.getUnreadMessages(driverId, messageType, tenantId);
            return Result.success(result, "获取未读消息列表成功");
        } catch (Exception e) {
            log.error("获取未读消息列表异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("获取未读消息列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/recent/{driverId}")
    @Operation(summary = "获取最近消息列表", description = "获取指定司机的最近消息列表")
    public Result<List<DriverMessage>> getRecentMessages(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "10") Integer limit,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            List<DriverMessage> result = driverMessageService.getRecentMessages(driverId, limit, tenantId);
            return Result.success(result, "获取最近消息列表成功");
        } catch (Exception e) {
            log.error("获取最近消息列表异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("获取最近消息列表失败: " + e.getMessage());
        }
    }

    @PostMapping("/send")
    @Operation(summary = "发送消息", description = "发送消息给司机")
    public Result<Boolean> sendMessage(
            @Parameter(description = "消息信息", required = true) @Valid @RequestBody DriverMessage message) {
        try {
            boolean result = driverMessageService.sendMessage(message);
            return Result.success(result, "发送消息成功");
        } catch (Exception e) {
            log.error("发送消息异常: driverId={}, messageType={}, tenantId={}", 
                     message.getDriverId(), message.getMessageType(), message.getTenantId(), e);
            return Result.error("发送消息失败: " + e.getMessage());
        }
    }

    @PostMapping("/send-to-driver")
    @Operation(summary = "发送消息给指定司机", description = "发送消息给指定司机")
    public Result<Boolean> sendMessageToDriver(
            @Parameter(description = "司机ID", required = true) @RequestParam Long driverId,
            @Parameter(description = "消息类型", required = true) @RequestParam Integer messageType,
            @Parameter(description = "消息标题", required = true) @RequestParam String title,
            @Parameter(description = "消息内容", required = true) @RequestParam String content,
            @Parameter(description = "发送人ID") @RequestParam(required = false) Long senderId,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.sendMessageToDriver(driverId, messageType, title, content, senderId, tenantId);
            return Result.success(result, "发送消息成功");
        } catch (Exception e) {
            log.error("发送消息给指定司机异常: driverId={}, messageType={}, tenantId={}", driverId, messageType, tenantId, e);
            return Result.error("发送消息失败: " + e.getMessage());
        }
    }

    @PostMapping("/send-to-all")
    @Operation(summary = "发送消息给所有司机", description = "发送消息给所有司机")
    public Result<Map<String, Object>> sendMessageToAllDrivers(
            @Parameter(description = "消息类型", required = true) @RequestParam Integer messageType,
            @Parameter(description = "消息标题", required = true) @RequestParam String title,
            @Parameter(description = "消息内容", required = true) @RequestParam String content,
            @Parameter(description = "发送人ID") @RequestParam(required = false) Long senderId,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Map<String, Object> result = driverMessageService.sendMessageToAllDrivers(messageType, title, content, senderId, tenantId);
            return Result.success(result, "发送消息给所有司机完成");
        } catch (Exception e) {
            log.error("发送消息给所有司机异常: messageType={}, tenantId={}", messageType, tenantId, e);
            return Result.error("发送消息给所有司机失败: " + e.getMessage());
        }
    }

    @PostMapping("/send-batch")
    @Operation(summary = "批量发送消息", description = "批量发送消息给多个司机")
    public Result<Map<String, Object>> sendBatchMessages(
            @Parameter(description = "司机ID列表", required = true) @RequestBody List<Long> driverIds,
            @Parameter(description = "消息类型", required = true) @RequestParam Integer messageType,
            @Parameter(description = "消息标题", required = true) @RequestParam String title,
            @Parameter(description = "消息内容", required = true) @RequestParam String content,
            @Parameter(description = "发送人ID") @RequestParam(required = false) Long senderId,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Map<String, Object> result = driverMessageService.sendBatchMessages(driverIds, messageType, title, content, senderId, tenantId);
            return Result.success(result, "批量发送消息完成");
        } catch (Exception e) {
            log.error("批量发送消息异常: messageType={}, tenantId={}", messageType, tenantId, e);
            return Result.error("批量发送消息失败: " + e.getMessage());
        }
    }

    @PostMapping("/mark-read/{id}")
    @Operation(summary = "标记消息已读", description = "标记指定消息为已读状态")
    public Result<Boolean> markMessageAsRead(
            @Parameter(description = "消息ID", required = true) @PathVariable Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.markAsRead(id, tenantId);
            return Result.success(result, "标记消息已读成功");
        } catch (Exception e) {
            log.error("标记消息已读异常: id={}, tenantId={}", id, tenantId, e);
            return Result.error("标记消息已读失败: " + e.getMessage());
        }
    }

    @PostMapping("/mark-unread/{id}")
    @Operation(summary = "标记消息未读", description = "标记指定消息为未读状态")
    public Result<Boolean> markMessageAsUnread(
            @Parameter(description = "消息ID", required = true) @PathVariable Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.markAsUnread(id, tenantId);
            return Result.success(result, "标记消息未读成功");
        } catch (Exception e) {
            log.error("标记消息未读异常: id={}, tenantId={}", id, tenantId, e);
            return Result.error("标记消息未读失败: " + e.getMessage());
        }
    }

    @PostMapping("/batch-mark-read")
    @Operation(summary = "批量标记消息已读", description = "批量标记多个消息为已读状态")
    public Result<Boolean> batchMarkAsRead(
            @Parameter(description = "消息ID列表", required = true) @RequestBody List<Long> ids,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.batchMarkAsRead(ids, tenantId);
            return Result.success(result, "批量标记消息已读成功");
        } catch (Exception e) {
            log.error("批量标记消息已读异常: tenantId={}", tenantId, e);
            return Result.error("批量标记消息已读失败: " + e.getMessage());
        }
    }

    @PostMapping("/mark-all-read/{driverId}")
    @Operation(summary = "标记所有消息已读", description = "标记指定司机的所有消息为已读状态")
    public Result<Boolean> markAllAsRead(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.markAllAsRead(driverId, messageType, tenantId);
            return Result.success(result, "标记所有消息已读成功");
        } catch (Exception e) {
            log.error("标记所有消息已读异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("标记所有消息已读失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除消息", description = "删除指定消息")
    public Result<Boolean> deleteMessage(
            @Parameter(description = "消息ID", required = true) @PathVariable Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.deleteMessage(id, tenantId);
            return Result.success(result, "删除消息成功");
        } catch (Exception e) {
            log.error("删除消息异常: id={}, tenantId={}", id, tenantId, e);
            return Result.error("删除消息失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/batch-delete")
    @Operation(summary = "批量删除消息", description = "批量删除多个消息")
    public Result<Boolean> batchDeleteMessages(
            @Parameter(description = "消息ID列表", required = true) @RequestBody List<Long> ids,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.batchDeleteMessages(ids, tenantId);
            return Result.success(result, "批量删除消息成功");
        } catch (Exception e) {
            log.error("批量删除消息异常: tenantId={}", tenantId, e);
            return Result.error("批量删除消息失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/clear/{driverId}")
    @Operation(summary = "清空司机消息", description = "清空指定司机的所有消息")
    public Result<Boolean> clearDriverMessages(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.clearDriverMessages(driverId, messageType, tenantId);
            return Result.success(result, "清空司机消息成功");
        } catch (Exception e) {
            log.error("清空司机消息异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("清空司机消息失败: " + e.getMessage());
        }
    }

    @GetMapping("/count/unread/{driverId}")
    @Operation(summary = "获取未读消息数量", description = "获取指定司机的未读消息数量")
    public Result<Long> getUnreadCount(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Long result = driverMessageService.getUnreadCount(driverId, messageType, tenantId);
            return Result.success(result, "获取未读消息数量成功");
        } catch (Exception e) {
            log.error("获取未读消息数量异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("获取未读消息数量失败: " + e.getMessage());
        }
    }

    @GetMapping("/count/total/{driverId}")
    @Operation(summary = "获取消息总数量", description = "获取指定司机的消息总数量")
    public Result<Long> getTotalCount(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Long result = driverMessageService.getTotalCount(driverId, messageType, tenantId);
            return Result.success(result, "获取消息总数量成功");
        } catch (Exception e) {
            log.error("获取消息总数量异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("获取消息总数量失败: " + e.getMessage());
        }
    }

    @GetMapping("/statistics")
    @Operation(summary = "获取消息统计信息", description = "获取消息相关的统计数据")
    public Result<Map<String, Object>> getStatistics(
            @Parameter(description = "司机ID") @RequestParam(required = false) Long driverId,
            @Parameter(description = "开始日期") @RequestParam(required = false) String startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) String endDate,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Map<String, Object> result = driverMessageService.getStatistics(driverId, startDate, endDate, tenantId);
            return Result.success(result, "获取消息统计信息成功");
        } catch (Exception e) {
            log.error("获取消息统计信息异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("获取消息统计信息失败: " + e.getMessage());
        }
    }

    @GetMapping("/export")
    @Operation(summary = "导出消息信息", description = "导出消息信息到Excel")
    public Result<List<Map<String, Object>>> exportMessages(
            @Parameter(description = "司机ID") @RequestParam(required = false) Long driverId,
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "是否已读") @RequestParam(required = false) Boolean isRead,
            @Parameter(description = "消息标题") @RequestParam(required = false) String title,
            @Parameter(description = "开始时间") @RequestParam(required = false) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) LocalDateTime endTime,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            List<Map<String, Object>> result = driverMessageService.exportMessages(driverId, messageType, isRead, title, startTime, endTime, tenantId);
            return Result.success(result, "导出消息信息成功");
        } catch (Exception e) {
            log.error("导出消息信息异常: tenantId={}", tenantId, e);
            return Result.error("导出消息信息失败: " + e.getMessage());
        }
    }

    @PostMapping("/import")
    @Operation(summary = "导入消息信息", description = "从Excel导入消息信息")
    public Result<Map<String, Object>> importMessages(
            @Parameter(description = "消息数据列表", required = true) @RequestBody List<Map<String, Object>> messageList,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Map<String, Object> result = driverMessageService.importMessages(messageList, tenantId);
            return Result.success(result, "导入消息信息完成");
        } catch (Exception e) {
            log.error("导入消息信息异常: tenantId={}", tenantId, e);
            return Result.error("导入消息信息失败: " + e.getMessage());
        }
    }

    @PostMapping("/template/create")
    @Operation(summary = "创建消息模板", description = "创建消息模板")
    public Result<Boolean> createMessageTemplate(
            @Parameter(description = "模板名称", required = true) @RequestParam String templateName,
            @Parameter(description = "消息类型", required = true) @RequestParam Integer messageType,
            @Parameter(description = "模板标题", required = true) @RequestParam String title,
            @Parameter(description = "模板内容", required = true) @RequestParam String content,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.createMessageTemplate(templateName, messageType, title, content, tenantId);
            return Result.success(result, "创建消息模板成功");
        } catch (Exception e) {
            log.error("创建消息模板异常: templateName={}, tenantId={}", templateName, tenantId, e);
            return Result.error("创建消息模板失败: " + e.getMessage());
        }
    }

    @GetMapping("/template/list")
    @Operation(summary = "获取消息模板列表", description = "获取消息模板列表")
    public Result<List<Map<String, Object>>> getMessageTemplates(
            @Parameter(description = "消息类型") @RequestParam(required = false) Integer messageType,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            List<Map<String, Object>> result = driverMessageService.getMessageTemplates(messageType, tenantId);
            return Result.success(result, "获取消息模板列表成功");
        } catch (Exception e) {
            log.error("获取消息模板列表异常: messageType={}, tenantId={}", messageType, tenantId, e);
            return Result.error("获取消息模板列表失败: " + e.getMessage());
        }
    }

    @PostMapping("/send-by-template")
    @Operation(summary = "使用模板发送消息", description = "使用消息模板发送消息")
    public Result<Map<String, Object>> sendMessageByTemplate(
            @Parameter(description = "模板ID", required = true) @RequestParam Long templateId,
            @Parameter(description = "司机ID列表", required = true) @RequestBody List<Long> driverIds,
            @Parameter(description = "模板参数") @RequestParam(required = false) Map<String, Object> templateParams,
            @Parameter(description = "发送人ID") @RequestParam(required = false) Long senderId,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Map<String, Object> result = driverMessageService.sendMessageByTemplate(templateId, driverIds, templateParams, senderId, tenantId);
            return Result.success(result, "使用模板发送消息完成");
        } catch (Exception e) {
            log.error("使用模板发送消息异常: templateId={}, tenantId={}", templateId, tenantId, e);
            return Result.error("使用模板发送消息失败: " + e.getMessage());
        }
    }

    @PostMapping("/schedule-send")
    @Operation(summary = "定时发送消息", description = "定时发送消息")
    public Result<Boolean> scheduleSendMessage(
            @Parameter(description = "司机ID列表", required = true) @RequestBody List<Long> driverIds,
            @Parameter(description = "消息类型", required = true) @RequestParam Integer messageType,
            @Parameter(description = "消息标题", required = true) @RequestParam String title,
            @Parameter(description = "消息内容", required = true) @RequestParam String content,
            @Parameter(description = "发送时间", required = true) @RequestParam LocalDateTime sendTime,
            @Parameter(description = "发送人ID") @RequestParam(required = false) Long senderId,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.scheduleSendMessage(driverIds, messageType, title, content, sendTime, senderId, tenantId);
            return Result.success(result, "定时发送消息设置成功");
        } catch (Exception e) {
            log.error("定时发送消息异常: messageType={}, sendTime={}, tenantId={}", messageType, sendTime, tenantId, e);
            return Result.error("定时发送消息失败: " + e.getMessage());
        }
    }

    @GetMapping("/push-settings/{driverId}")
    @Operation(summary = "获取推送设置", description = "获取司机的消息推送设置")
    public Result<Map<String, Object>> getPushSettings(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            Map<String, Object> result = driverMessageService.getPushSettings(driverId, tenantId);
            return Result.success(result, "获取推送设置成功");
        } catch (Exception e) {
            log.error("获取推送设置异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("获取推送设置失败: " + e.getMessage());
        }
    }

    @PostMapping("/push-settings/{driverId}")
    @Operation(summary = "更新推送设置", description = "更新司机的消息推送设置")
    public Result<Boolean> updatePushSettings(
            @Parameter(description = "司机ID", required = true) @PathVariable Long driverId,
            @Parameter(description = "推送设置", required = true) @RequestBody Map<String, Object> settings,
            @Parameter(description = "租户ID", required = true) @RequestParam Long tenantId) {
        try {
            boolean result = driverMessageService.updatePushSettings(driverId, settings, tenantId);
            return Result.success(result, "更新推送设置成功");
        } catch (Exception e) {
            log.error("更新推送设置异常: driverId={}, tenantId={}", driverId, tenantId, e);
            return Result.error("更新推送设置失败: " + e.getMessage());
        }
    }
}